﻿using System;
using System.Linq;
using System.Web;
using System.Xml;
using System.Net;
using Shut;

/// <summary>
/// Summary description for Class1
/// </summary>
/// 
namespace Shut.HttpModules
{
	public partial class UrlRewrite : IHttpModule
	{
		public void Init(HttpApplication application)
		{

			application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
			if (!SiteSettings.Instance.DebugMode)
			    application.Error += (new EventHandler(this.Application_Error));

			
			
		}
		
		
		protected void Application_BeginRequest(Object sender, EventArgs e)
		{
			// read request
			HttpContext context = ((HttpApplication)sender).Context;

			
			string url = context.Request.RawUrl.ToUpperInvariant();
			

			url = url.Replace(".ASPX.CS", "");

			if (!url.Contains("404.ASPX"))
			{
				// match in sitemap first

				RewritePage(context, url);
			}

		}

		private static void RewritePage(HttpContext context, string url)
		{
			// set the current sitemap
			SiteMapProvider ShutMap = SiteMap.Providers[SiteSettings.Instance.SiteMapName];

			if (ShutMap.CurrentNode != null)
			{

				if (!String.IsNullOrEmpty(ShutMap.CurrentNode["realPath"]))
				{
					context.RewritePath(ShutMap.CurrentNode["realPath"]);
					
				}
			}else{
				// check real file
				string s = context.Server.MapPath(context.Request.AppRelativeCurrentExecutionFilePath);
				
				if (!System.IO.File.Exists(s)){
					throw new HttpException(404, "Page not found");
				}
				
			
			}
			
		}
		

		public void Dispose() { }


		private static string ExtractTitle(HttpContext context, string url)
		{
			url = url.ToLowerInvariant().Replace("---", "-");
			// no extension there
			if (url.EndsWith("/"))
			{
				// get rid of trailing slash
				url = url.Substring(0, url.Length - 1);
				context.Response.AppendHeader("location", url);
				context.Response.StatusCode = 301;
			}
			if (url.IndexOf("?") > -1)
			{
				url = url.Substring(0, url.IndexOf("?"));
			}
			int index = url.LastIndexOf("/") + 1;
			string title = url.Substring(index);
			return context.Server.UrlEncode(title);
		}

		private static string GetQueryString(HttpContext context)
		{
			string query = context.Request.QueryString.ToString();
			if (!string.IsNullOrEmpty(query))
				return "&" + query;

			return string.Empty;
		}

		protected void Application_Error(Object sender, EventArgs e)
		{
			
			HttpContext context = ((HttpApplication)sender).Context;
			Exception exception = context.Server.GetLastError();
			ShException ex = exception as ShException;

			
			// look for custome shut exceptions first

			if (ex == null)
			{
			
				if (exception.InnerException != null) exception = exception.InnerException;

				 ex = new ShException(exception.Message, exception, false);
			}

			// log
			try
			{
				ErrorLogger.LogError(ex.ErrorDetails, ex.ToString());
			}
			catch (System.IO.IOException logexception)
			{
				// do nothing for now

				context.Response.Redirect(System.Configuration.ConfigurationManager.AppSettings.Get("ErrorPage") + "?e=" + context.Server.UrlEncode(logexception.Message));
			}

			if (ex.IsAjax)
			{
				context.Response.Write(ex.Message);
			}
			else
			{
				string qs = "?p=" + context.Request.CurrentExecutionFilePath +"&r="+ context.Request.UrlReferrer;

				if (ex.isPageNotFound)
				{
					context.Response.Redirect(TocNode.GetNode("PageNotFound").Url+qs); //TODO: hide it, like in a webservice to call ga instead of the clear qs
					
				}
				else
				{
					context.Response.Redirect(System.Configuration.ConfigurationManager.AppSettings.Get("ErrorPage") + qs + "&e=" + context.Server.UrlEncode(ex.Message));
				}
			}
			context.Server.ClearError();
			context.Response.End();
			
		}
		

	}


}